import {Base64} from './base64.js'
import {util} from './crypto.js'
import {HMAC} from './hmac.js'
import {SHA1} from './sha1.js'
import api from "../api.js";
import * as dialog from '../dialog.js'

const policyText = {
    "expiration": "2034-01-01T12:00:00.000Z", // 设置Policy的有效期，格式为UTC时间。如果Policy失效，将无法上传文件。
    "conditions": [
        ["content-length-range", 0, 1048576000] // 限制上传文件的大小，单位为字节，此处限制文件大小为1 GB。如果上传的文件大小超过此限制，文件将无法上传到OSS。如果未设置该限制，则默认文件大小最大为5 GB。
    ]
}

const getSignature = OSSAccessKeySecret => {
    const policy = Base64.encode(JSON.stringify(policyText))
    const bytes = HMAC(SHA1, policy, OSSAccessKeySecret, {asBytes: true})
    const signature = util.bytesToBase64(bytes)
    return {policy, signature}
}

const callback = async (id, result) => {
    const res = await api.file.callback({id, result})
    return res.data
}

export const upload = fileObj => {
    return new Promise(async (resolve, reject) => {
        
        const filePath = fileObj.url
        
        const type = fileObj.type
        const size = fileObj.size
        
        const name = fileObj.name || filePath.substring(filePath.lastIndexOf('/') + 1)
        const res = await api.file.getObject({name, size, type})
        
        if (res.success) {
            const {id, url, objectName, name, securityToken} = res.data
            const OSSAccessKeyId = res.data.accessKey
            const OSSAccessKeySecret = res.data.secretKey
            const {policy, signature} = getSignature(OSSAccessKeySecret)
            
            uni.uploadFile({
                url, filePath,
                name: 'file',
                formData: {
                    name, key: objectName,
                    OSSAccessKeyId, policy, signature,
                    'x-oss-security-token': securityToken,
                    success_action_status: '200'
                },
                success: async () => {
                    resolve(await callback(id, true))
                },
                fail: async () => {
                    await callback(id, false)
                    await dialog.toast({
                        title: '上传失败'
                    })
                    reject('上传失败')
                }
            })
        } else {
            reject('上传失败')
        }
    })
}
